<template>
	<view class="page-content">
		<view class="form">
			<view class="form-content">
				<canvas class="form-content__canvas" canvas-id="canvas_sign" @touchstart="touchstart"
					@touchmove="touchmove" @touchend="touchend" disable-scroll="true" ref="canvasLL"></canvas>
			</view>

			<view class="form-button">
				<button class="form-button__save" @click="autographClick(2)">上屏</button>
				<button class="form-button__reset" @click="autographClick(1)">重写</button>
				
				<!-- <button class="form-button__preview" @click="autographClick(3)">预览</button> -->
			</view>
		</view>

	</view>
</template>

<script>
	const MAX_V = 1; // 最大书写速度
	const MIN_V = 0; // 最小书写速度
	const MAX_LINE_WIDTH = 16; // 最大笔画宽度
	const MIN_LINE_WIDTH = 4; // 最小笔画宽度
	const MAX_LINE_DIFF = .03; // 两点之间笔画宽度最大差异
	let context = null; // canvas上下文
	let lastPoint = null; // 包含上一点笔画信息的对象

	export default {
		data() {
			return {
				canvasCtx: '', //绘图图像
				points: [], //路径点集合
				hasSign: false,
				isInit: false,
			}
		},
		onLoad(query) {
			this.canvasCtx = uni.createCanvasContext('canvas_sign', this) //创建绘图对象
			//设置画笔样式
			// this.canvasCtx.lineWidth = (MAX_LINE_WIDTH + MIN_LINE_WIDTH) / 2

			// 设置线条的端点样式
			this.canvasCtx.lineCap = 'round'
			// 设置线条的交点样式
			this.canvasCtx.lineJoin = 'round'

		},
		methods: {
			//触摸开始，获取到起点
			touchstart: function(e) {
				if (!this.isInit) {
					this.isInit = true
					this.autographClick(1);
				}
				let startX = e.changedTouches[0].x
				let startY = e.changedTouches[0].y
				let startPoint = {
					X: startX,
					Y: startY
				}
				this.points.push(startPoint)

				//每次触摸开始，开启新的路径
				// console.log(this.points, "point11")
				this.canvasCtx.beginPath()
			},

			//触摸移动，获取到路径点
			touchmove: function(e) {
				let moveX = e.changedTouches[0].x
				let moveY = e.changedTouches[0].y
							
				let movePoint = {
					X: moveX,
					Y: moveY,
					T: new Date().getTime(),
					W: (MAX_LINE_WIDTH + MIN_LINE_WIDTH) / 2
				}
				// console.log(movePoint.T, movePoint.W,"ww")
				this.points.push(movePoint) //存点
				
				// console.log(this.points, "point222")
				if (lastPoint) {
					// console.log(lastPoint.T, movePoint.T)
					movePoint.W = this.calcLineWidth(movePoint); // 重新赋值宽度，覆盖默认值 
					this.canvasCtx.beginPath();
					this.canvasCtx.strokeStyle = '#000';
					this.canvasCtx.lineCap = 'round';
					this.canvasCtx.lineJoin = 'round';
					this.canvasCtx.lineWidth = movePoint.W;
					this.canvasCtx.moveTo(lastPoint.X, lastPoint.Y);
					this.canvasCtx.lineTo(movePoint.X, movePoint.Y);
					this.canvasCtx.stroke();
				}
				lastPoint = movePoint; // 结束前保存当前点为上一点
				
				let len = this.points.length
				if (len >= 2) {
					this.draw() //绘制路径
				}

			},
			
			// 计算当前点的宽度，书写速度越快，笔画宽度越小，呈现出笔锋的感觉（笑）
			calcLineWidth: function (movePoint) {
				let consuming = movePoint.T - lastPoint.T; // 两点之间耗时
				// console.log("consuming", consuming)
				if (!consuming) return lastPoint.W; // 如果当前点用时为0，返回上点的宽度。
				let maxWidth = Math.min(MAX_LINE_WIDTH, lastPoint.W * (1 + MAX_LINE_DIFF)); // 当前点的最大宽度
				// 当前点的最小宽度，变细时速度快所以宽度变化要稍快
				let minWidth = Math.max(MIN_LINE_WIDTH, lastPoint.W * (1 - MAX_LINE_DIFF * 3)); 
				// 两点之间距离
				let distance = Math.sqrt(Math.pow(movePoint.X - lastPoint.X, 2) + Math.pow(movePoint.Y - lastPoint.Y, 2)); 
				let speed = Math.max(Math.min(distance / consuming, MAX_V), MIN_V); /*当前点速度*/
				let lineWidth = Math.max(Math.min(MAX_LINE_WIDTH * (1 - speed / MAX_V), maxWidth), minWidth); /* 当前点宽度 */
				// console.log(maxWidth, minWidth, distance, speed, lineWidth)
				return lineWidth;
			},

			// 触摸结束，将未绘制的点清空防止对后续路径产生干扰
			touchend: function() {
				this.points = []
				this.canvasCtx.draw(true)
				lastPoint = null;
			},

			/* ***********************************************
			#   绘制笔迹
			#	1.为保证笔迹实时显示，必须在移动的同时绘制笔迹
			#	2.为保证笔迹连续，每次从路径集合中区两个点作为起点（moveTo）和终点(lineTo)
			#	3.将上一次的终点作为下一次绘制的起点（即清除第一个点）
			************************************************ */
			draw: function() {
				let point1 = this.points[0]
				let point2 = this.points[1]
				this.points.shift()
				this.canvasCtx.moveTo(point1.X, point1.Y)
				this.canvasCtx.lineTo(point2.X, point2.Y)
				this.canvasCtx.stroke()
				this.canvasCtx.draw(true)
				this.hasSign = true
			},

			// 按钮点击操作
			autographClick(type) {
				let that = this
				if (type === 1) {
					//清空画布
					this.hasSign = false
					uni.getSystemInfo({
						success: function(res) {
							let canvas = uni.createSelectorQuery().select('.form-content__canvas')
							canvas.boundingClientRect().exec(function(data) {
								// console.log('canvas', data)
								// console.log('canvas wh:' + data[0].width + 'X' + data[0].height)
								let canvasw = Math.ceil(data[0].width)
								let canvash = Math.ceil(data[0].height)
								that.canvasCtx.fillStyle = '#fdefed'
								that.canvasCtx.fillRect(0, 0, canvasw, canvash)
								that.canvasCtx.draw(true)
							})
						}
					})

				} else {
					if (!this.hasSign) {
						uni.showToast({
							title: '签名不能为空',
							icon: 'none',
							duration: 2000
						})
						return
					}
					uni.getSystemInfo({
						success: function(res) {
							let canvas = uni.createSelectorQuery().select('.form-content__canvas')
							canvas.boundingClientRect().exec(function(data) {
								// console.log('canvas saveSign:', data[0].width + 'X' + data[0].height)
								let canvasw = Math.ceil(data[0].width)
								let canvash = Math.ceil(data[0].height)
								uni.canvasToTempFilePath({
									destWidth: canvasw,
									destHeight: canvash,
									fileType: 'png',
									canvasId: 'canvas_sign',
									success: function(res) {
										console.log('图片导出成功：', res)
										let path = res.tempFilePath

										// 保存图片
										if (type === 2) {
											that.uploadPic(path)
										} 
										// else if (type === 3) {
										// 	// 预览图片
										// 	uni.previewImage({
										// 		urls: [path]
										// 	})
										// }
									},
									fail: (err) => {
										// http://tmp/2LVQyvzddk2R820a9009dff43323d8e7fc9ef7a8d076.jpg
										console.log('图片导出失败：', err)
									}
								})
							})
						}
					})
				}
			},

			// 图片上传处理
			uploadPic(tempFile) {
				// 1、将本地图片上传到服务器
				// 2、将返回的链接，上传到我们的服务器平台
				console.log("------:", tempFile);
				uni.showLoading({
					title: '正在上传中...'
				})
				setTimeout(() => {
					uni.showToast({
						title: '假装签名上传成功',
						duration: 2000,
						icon: 'none'
					});
				}, 1000);
			},
			
		}
	}
</script>

<style lang="scss" scoped>
	/*
	* 横屏后的适配方案
	* @param $rpx为需要转换的字号
	* @参考 https://blog.csdn.net/sdfsfsdscd/article/details/91375066
	**/
	@function tovmin($rpx) {
		@return #{$rpx * 100 / 750}vmin;
	}

	.page-content {
		width: 100vw;
		height: 100vh;

		.form {
			display: flex;
			// flex-direction: column;
			width: 100%;
			height: 100%;

			.form-content {
				width: 100%;
				height: 100%;

				&__canvas {
					height: 100%;
					width: 100%;
					background-color: #fdefed;
				}
				padding-right: tovmin(20);
			}

			.form-button {
				height: 100%;
				width: 20%;

				display: flex;
				flex-direction: column-reverse;
				// justify-content: space-around;
				background: #FFFFFF;
				box-shadow: 0 tovmin(4) tovmin(20) tovmin(2) rgba(183, 183, 183, 0.20);


				button {
					width: 14vw;
					margin-bottom: 8vh;

					height: tovmin(88);
					line-height: tovmin(88);
					border-radius: tovmin(48);
					text-align: center;
					font-size: tovmin(36);
					font-weight: bold;
				}

				button::after {
					border: none;
				}

				&__reset {
					color: #ff5642;
					border: tovmin(1) solid #ff5642;
				}

				&__save {
					color: #FFFFFF;
					background-image: linear-gradient(135deg, #ff8e81 0%, #ff5642 100%);
				}

				// &__preview {
				// 	color: #008AFE;
				// 	border: tovmin(1) solid #008AFE;
				// }
			}
		}
	}
</style>
